package particles;

import java.util.Random;

import processing.core.*;

//A class to describe an array of particles
public class ParticleSystem {
	
	private Particle[] particles;
	private PVector location;
	
	// constructor creates a number of particles at a location
	// with no initial velocity or acceleration
	public ParticleSystem(int numberOfParticles, PVector location, float lifetime, double angle){
		this.location = location;
		this.particles = new Particle[numberOfParticles];
		PVector acc = new PVector(0,0,0);
		PVector vel = new PVector(0,0,0);
		for (int i = 0; i < numberOfParticles; i++) {
			this.particles[i] = new Particle(acc, vel, location, lifetime, angle);
		}
	}

	// explodes the particles in the current system away from
	// a point of origin, with a certain acceleration
	// angle given in radians
	public void explode(float velocity, float dispersion, float angle, double width, double height){
		// divide a circle into n parts, where n = number of
		// particles in the system.
		double deltaDegree = (Math.PI * 2)/this.particles.length;
		Random randomGenerator = new Random();
		for (int i = 0; i < this.particles.length; i++){
			// modify the force by a random amount determined by dispersion 
			double v = velocity + ((randomGenerator.nextGaussian()-0.5)*dispersion);
			PVector velocityVector = new PVector((float) (width*Math.cos(deltaDegree*i)*v), (float) (height*Math.sin(deltaDegree*i)*v), (float) 0);
			//rotate velocity vector by angle degrees
			//angle = (float) -(angle+(Math.PI/2));
			velocityVector = new PVector((float) (velocityVector.x * Math.sin(angle) - velocityVector.y
			* Math.cos(angle)), (float) (velocityVector.x
			* Math.cos(angle) + velocityVector.y * Math.sin(angle)));
			this.particles[i].setVelocity(velocityVector);
			
			/*
			//add an acceleration at an angle alpha to the original velocity
			double alpha = -Math.PI/4;
			PVector accelerationVector = new PVector((float) (velocityVector.x*Math.cos(alpha) - velocityVector.y*Math.sin(alpha)), (float) (velocityVector.x*Math.sin(alpha) + velocityVector.y*Math.cos(alpha)), (float) 0);
			accelerationVector.div(20);
			this.particles[i].setAcceleration(accelerationVector);
			*/
			
		}
	}
	
	//returns the center point of the particle system
	public PVector getLocation(){
		return this.location;
	}
	
	//returns the number of particles in the system
	public int getLength(){
		return this.particles.length;
	}
	
	//returns a particle of the given int
	public Particle getParticle(int i){
		try {
			return this.particles[i];
		} catch (NullPointerException e) {
			return null;
		}
	}
	
	public ParticleSystem update()
	{
		for (Particle p : particles) {
			p.update();
		}
		return this;
	}
	
	public Particle[] getParticles() 
	{
		return particles;
	}
}
